#include "AI.h"


AI::AI(int _difficulty_level, int _player)
{
	difficulty_level = _difficulty_level;
	player = _player;
}

//int AI::FindPieces(Board &board)
//{
//	unsigned index = 0;
//
//	for (unsigned i=0; 1 < BOARD_X; i++)
//	{
//		for(unsigned j=0; 1 < BOARD_X; j++)
//		{
//			if (player == 1)
//			{
//				if (board.GetValue(i,j) == player || board.GetValue(i,j) == player+2)
//				{
//					men[index].SetPiece(i,j,board.GetValue(i,j));
//					index++;
//				}
//				
//			}
//		}
//	}
//	return index;
//}

/*********************************************************
 AI::AnalyzeMove()
 ********************************************************/
 int AI::AnalyzeMove(Checkers &yourTurn)
{
	Board *move = yourTurn.GetBoard(); // Gets the board
	
	int score;
	
	if(player==CHECKERS_PLAYER2)
		score = move->GetPlayer2PieceCount() - move->GetPlayer1PieceCount(); // calculates the score
	else
		score = move->GetPlayer1PieceCount() - move->GetPlayer2PieceCount();

	return score;
}

/*********************************************************
  AI::Alpha_Beta()
 ********************************************************/
int AI::Alpha_Beta(bool maxNode, int alpha, int beta, int currentDepth, Checkers &yourTurn, Board currentState)
{

	if (currentDepth == difficulty_level) // if at the bottom of the tree
		return AnalyzeMove(yourTurn); // evaluate move 
	
	if (player == CHECKERS_PLAYER2) // if AI is Player 2 
	{
		if (yourTurn.GetStatus() == STATUS_PLAYER1_WON) // if this move means player 1 wins
		{
			cout << currentState;
			return ALPHA; // this is the worst move that can be made
		}
		if (yourTurn.GetStatus() == STATUS_PLAYER2_WON) // if this move means player 2 wins
		{
			cout << currentState;
			return BETA; // this is the best move
		}
	}

	else // AI is Player 1
	{
		if (yourTurn.GetStatus() == STATUS_PLAYER2_WON) // if this move means player 2 wins
		{
			cout << currentState;
			return ALPHA; // this is the worst move that can be made
		}

		if (yourTurn.GetStatus() == STATUS_PLAYER1_WON) // if this move means player 1 wins
		{
			cout << currentState;
			return BETA; // this is the best move
		}
	}
	
	if (maxNode) 
	{
		if (yourTurn.GetCurrentPlayer() != player)
			yourTurn.ChangePlayerTurn();

		vector<Path*> moves = yourTurn.GetMoves(); // gets the legal moves for this turn 
		int score; // the value of this node
		Board *PnextMove;
		
		unsigned maxMoves = moves.size();
		
		for (unsigned i = 0; i < maxMoves; i++)  
		{
			if (yourTurn.GetCurrentPlayer() != player)
				yourTurn.ChangePlayerTurn();

			moves = yourTurn.GetMoves(); // Gets the possible moves for this turn

			// Try the move
			yourTurn.FollowPath(moves[i]);
			
			PnextMove = yourTurn.GetBoard(); // gets the next move

			score = Alpha_Beta(false,alpha,beta,currentDepth+1,yourTurn,*PnextMove); // move deeper down the tree

			if(score > alpha) // if the score is greater than alpha
				alpha = score; // score becomes new alpha

			if(alpha >= beta) // if alpha is less than or equal to beta
			{
				yourTurn.SetBoard(currentState); //reset the game board
				yourTurn.ChangePlayerTurn(); // reset the turn

				return alpha;  // cut off	
			}

			 yourTurn.SetBoard(currentState); //reset the game board
			 yourTurn.ChangePlayerTurn(); // reset the turn
		}
		return alpha; 
	}

	else
	{
		if (yourTurn.GetCurrentPlayer() == player)
			yourTurn.ChangePlayerTurn();

		vector<Path*> moves = yourTurn.GetMoves(); // gets the legal moves for this turn 
		int score; // the value of this node
		Board *PnextMove;
		unsigned maxMoves = moves.size();
		
		for (unsigned i = 0; i < maxMoves; i++) 
		{
			if (yourTurn.GetCurrentPlayer() == player)
			yourTurn.ChangePlayerTurn();

			moves = yourTurn.GetMoves(); // gets the legal moves for this turn 

			// Try the move
			yourTurn.FollowPath(moves[i]);
			
			PnextMove = yourTurn.GetBoard(); // gets the next move

			score = Alpha_Beta(true,alpha,beta,currentDepth+1,yourTurn,*PnextMove); // move deeper down the tree

			if(score < beta) // if the score is less than beta
				beta = score; // score becomes new beta

			if(alpha >= beta) // if alpha is less than or equal to beta
			{
				yourTurn.SetBoard(currentState); //reset the game board
				yourTurn.ChangePlayerTurn(); // reset the turn

				return beta;  // cut off
			}

			 yourTurn.SetBoard(currentState); //reset the game board
			 yourTurn.ChangePlayerTurn(); // reset the turn
		}
	return beta;
	}
}

/*********************************************************
 * AI::FinalMove()
 ********************************************************/

void AI::FinalMove(Checkers &yourTurn, Board currentState)
{
	int score; // the value of this node
	int bestScore = ALPHA;
	int bestMove = 0;	
	vector<Path*> moves = yourTurn.GetMoves(); // Gets the possible moves for this turn
	unsigned maxMoves = moves.size();
	Board *PnextMove;// the board after this move is made
	unsigned i = 1;

	if (maxMoves==1)
		i = 0;

		
	for (i; i < maxMoves; i++)// gets the legal moves for this turn
	{
		if (yourTurn.GetCurrentPlayer() != player)
			yourTurn.ChangePlayerTurn();

		moves = yourTurn.GetMoves(); // Gets the possible moves for this turn

		// Try the move
		yourTurn.FollowPath(moves[i]);

		PnextMove = yourTurn.GetBoard();			

		score = Alpha_Beta(false,ALPHA,BETA,0,yourTurn,*PnextMove); // move deeper down the tree

		if (score > bestScore)
		{
			bestScore = score;
			bestMove = i;
		}

		yourTurn.SetBoard(currentState); //reset the game board
		yourTurn.ChangePlayerTurn(); // reset the turn

	}

	//yourTurn.SetMovesWithNoCapture(nonCaptures);
	moves = yourTurn.GetMoves(); // gets the legal moves for this turn 

	// execute the best move
	yourTurn.FollowPath(moves[bestMove]);

}

